package kq

import (
	"context"
	"encoding/json"
	"fmt"
	"regexp"
	"strings"
	"time"

	"mall/common/cachex"
	"mall/common/mqueuex"
	"mall/service/backend/common/wechat"
	"mall/service/backend/rmq/internal/svc"

	// "github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

/**
 * Listening to the payment flow status change notification message queue
 */
type UploadShipmentInfoToWeBackendMq struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUploadShipmentInfoToWeBackendMq(ctx context.Context, svcCtx *svc.ServiceContext) *UploadShipmentInfoToWeBackendMq {
	return &UploadShipmentInfoToWeBackendMq{
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UploadShipmentInfoToWeBackendMq) Consume(_, val string) error {
	// 解析数据
	var message mqueuex.UploadShipmentInfoToWeBackendMessage
	if err := json.Unmarshal([]byte(val), &message); err != nil {
		logx.Errorw("UploadShipmentInfoToWeBackendMq.Consume json.Unmarshal err", logx.Field("detail", err.Error()))
		return err
	}

	// logrus.Info(fmt.Sprintf("UploadShipmentInfoToWeBackendMq message: %+v", message))

	// 执行业务..
	if err := l.execService(message); err != nil {
		logx.Errorw("UploadShipmentInfoToWeBackendMq.execService err", logx.Field("detail", err.Error()),
			logx.Field("val", val), logx.Field("message", fmt.Sprintf("%+v", message)))
		return err
	}

	return nil
}

func (l *UploadShipmentInfoToWeBackendMq) execService(message mqueuex.UploadShipmentInfoToWeBackendMessage) error {
	var err error
	now := time.Now()
	appId := l.svcCtx.Config.WxMiniConf.AppId
	secret := l.svcCtx.Config.WxMiniConf.Secret
	var transactionId, trackingNo, productName, phone, openId string
	if len(strings.TrimSpace(message.TransactionId)) > 0 {
		transactionId = strings.TrimSpace(message.TransactionId)
	}
	if len(strings.TrimSpace(message.TrackingNo)) > 0 {
		trackingNo = strings.TrimSpace(message.TrackingNo)
	}
	if len(strings.TrimSpace(message.ProductName)) > 0 {
		productName = strings.TrimSpace(message.ProductName)
	}
	if len(strings.TrimSpace(message.Phone)) > 0 {
		phone, err = l.maskPhoneNumber(message.Phone)
		if err != nil {
			phone = "1**********"
		}
	}
	if len(strings.TrimSpace(message.OpenId)) > 0 {
		openId = strings.TrimSpace(message.OpenId)
	}
	data := map[string]any{
		"order_key": map[string]any{
			"order_number_type": 2,
			"transaction_id":    transactionId, //交易单号
		},
		"delivery_mode":  1,
		"logistics_type": 1,
		"shipping_list": []map[string]any{
			{
				"tracking_no":     trackingNo, //交易单号
				"express_company": "STO",
				"item_desc":       productName,
				"contact": map[string]string{
					"consignor_contact": phone,
				},
			},
		},
		"upload_time": now.Format(time.RFC3339Nano),
		"payer": map[string]string{
			"openid": openId,
		},
	}

	var accessToken string
	key := cachex.WexinAccessToken
	if accessToken, err = l.svcCtx.BizRedis.GetCtx(l.ctx, key); err != nil || len(strings.TrimSpace(accessToken)) == 0 {
		accessToken, err = wechat.GetWeAccessToken(appId, secret)
		if err != nil {
			return err
		}
	}
	if len(strings.TrimSpace(accessToken)) > 0 {
		err = l.svcCtx.BizRedis.SetCtx(l.ctx, key, accessToken)
		if err != nil {
			return err
		}
		err = wechat.UploadOrderToWeBackend(l.ctx, l.svcCtx.BizRedis, appId, secret, accessToken, data, false)
		if err != nil {
			return err
		}
	}

	return nil
}

func (l *UploadShipmentInfoToWeBackendMq) maskPhoneNumber(phone string) (string, error) {
	match, err := regexp.MatchString(`^1[3-9]\d{9}$`, phone)
	if err != nil {
		return "", err
	}
	if !match {
		return "", fmt.Errorf("phone is invalid")
	}

	re := regexp.MustCompile(`^(\d{3})(\d{4})(\d{4})$`)
	return re.ReplaceAllString(phone, "$1****$3"), nil
}
